package znet

import (
	"bytes"
	"encoding/binary"
	"errors"
	"github.com/aceld/zinx/utils"
	"github.com/aceld/zinx/ziface"
)

//DataPack 封包拆包类实例，暂时不需要成员
type DataPack struct{}

//NewDataPack 封包拆包实例初始化方法
func NewDataPack() *DataPack {
	return &DataPack{}
}

//GetHeadLen 获取包头长度方法
func (dp *DataPack) GetHeadLen() uint32 {
	//ID uint32(4字节) +  DataLen uint32(4字节)
	return 13
}

//Pack 封包方法(压缩数据)
func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
	//创建一个存放bytes字节的缓冲
	dataBuff := bytes.NewBuffer([]byte{})

	////写head 0x7b 0x7b
	//if err := binary.Write(dataBuff, binary.LittleEndian, uint8(0x7b)); err != nil {
	//	return nil, err
	//}
	//if err := binary.Write(dataBuff, binary.LittleEndian, uint8(0x7b)); err != nil {
	//	return nil, err
	//}
	//
	//
	////写msgID
	//if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgID()); err != nil {
	//	return nil, err
	//}

	//写data数据
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetData()); err != nil {
		return nil, err
	}


	////写入CRC校验结果
	//crcResult := tool.CheckCrc(dataBuff.Bytes()[2:])
	//if err := binary.Write(dataBuff,binary.LittleEndian,crcResult); err !=nil{
	//	return nil, err
	//}
	//
	////写入帧尾0x7d 0x7d
	//if err := binary.Write(dataBuff,binary.LittleEndian,uint8(0x7d)); err !=nil{
	//	return nil, err
	//}
	//if err := binary.Write(dataBuff,binary.LittleEndian,uint8(0x7d)); err !=nil{
	//	return nil, err
	//}



	return dataBuff.Bytes(), nil
}

//Unpack 拆包方法(解压数据)
func (dp *DataPack) Unpack(binaryData []byte,dateLen int,askType int) (ziface.IMessage, error) {



	//只解压head的信息，得到dataLen和msgID
	msg := &Message{}

	if binaryData[0] == 0xA8 && binaryData[1] == 0X01{

		if dateLen == 7{
			msg.ID = 0
			msg.Data = append(msg.Data, binaryData...)
		}else if dateLen == 13{
			msg.ID = uint8(askType)
			msg.DataLen = uint32(binaryData[12])
			msg.AppendData(binaryData)
		}

	}else{
		return nil, errors.New("不能识别的帧头")
	}


	//判断dataLen的长度是否超出我们允许的最大包长度
	if utils.GlobalObject.MaxPacketSize > 0 && msg.DataLen > utils.GlobalObject.MaxPacketSize {
		return nil, errors.New("too large msg data received")
	}

	//这里只需要把head的数据拆包出来就可以了，然后再通过head的长度，再从conn读取一次数据
	return msg, nil
}
